package org.springside.examples.miniweb.web.report;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.persistence.Transient;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspTagException;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springside.examples.miniweb.entity.report.AssignedReport;
import org.springside.examples.miniweb.entity.report.ColdPumpReport;
import org.springside.examples.miniweb.entity.report.CompressorReport;
import org.springside.examples.miniweb.entity.search.SearchForm;
import org.springside.examples.miniweb.service.account.AccountManager;
import org.springside.examples.miniweb.service.report.ColdPumpReportManager;
import org.springside.examples.miniweb.service.report.CompReportManager;

@Controller
@RequestMapping(value = "/performance")
public class PerformanceController extends ReportController<AssignedReport> {

	private ColdPumpReportManager<ColdPumpReport> coldManager;

	private CompReportManager<CompressorReport> comManager;

	private AccountManager accountManager;

	/**
	 * @param manager
	 *            the manager to set
	 */
	@Autowired
	public void setColdManager(ColdPumpReportManager<ColdPumpReport> coldManager) {
		this.coldManager = coldManager;
	}

	/**
	 * @param manager
	 *            the manager to set
	 */
	@Autowired
	public void setComManager(CompReportManager<CompressorReport> comManager) {
		this.comManager = comManager;
	}

	@RequestMapping(value = { "list", "" })
	public String list(Model model) {
		Page<AssignedReport> pages = new PageImpl<AssignedReport>(
				new ArrayList<AssignedReport>());
		initListPage(model);
		model.addAttribute("search", new SearchForm());
		model.addAttribute("reports", pages.getContent());
		model.addAttribute("pages", pages);
		return "reports/performanceList";
	}

	@RequestMapping(value = { "leadto/{reportId}" })
	public String leadto(@PathVariable("reportId") String reportId, Model model) {
		if (reportId.startsWith("COL")) {
			return "redirect:/report/cold/update/" + reportId.substring(3);
		}

		if (reportId.startsWith("COM")) {
			return "redirect:/report/comp/update/" + reportId.substring(3);
		}
		return list(model);
	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "search")
	public String search(@ModelAttribute("search") SearchForm searchForm,
			Model model, HttpServletRequest request) {
		model.addAttribute("search", searchForm);
		initListPage(model);
		List<AssignedReport> reports = null;

		if (searchForm.getPageNumber().equalsIgnoreCase("research")) {
			reports = new ArrayList<AssignedReport>();
			reports = Collections.synchronizedList(reports);
			reports.addAll(coldManager.getReportByUserName(searchForm
					.getUserName()));
			reports.addAll(comManager.getReportByUserName(searchForm
					.getUserName()));

			if (searchForm.getStatus() != null
					&& !searchForm.getStatus().equals("all")) {
				for (int i = 0; i < reports.size(); i++) {
					AssignedReport report = reports.get(i);
					if (!report.getStatus().equalsIgnoreCase(
							searchForm.getStatus())) {
						reports.remove(report);
						i--;
					}
				}
			}

			if (searchForm.getStartDate() != null) {
				for (int i = 0; i < reports.size(); i++) {
					AssignedReport report = reports.get(i);
					if (report.getScheduleFinish().before(
							searchForm.getStartDate())) {
						reports.remove(report);
						i--;
					}
				}
			}

			if (searchForm.getEndDate() != null) {
				for (int i = 0; i < reports.size(); i++) {
					AssignedReport report = reports.get(i);
					if (report.getScheduleFinish().after(
							searchForm.getEndDate())) {
						reports.remove(report);
						i--;
					}
				}
			}
			searchForm.setPageNumber("0");
			request.getSession().setAttribute("performanceList", reports);
			
		}else{
			reports = (List<AssignedReport>) request.getSession().getAttribute("performanceList");
		}

		Page<AssignedReport> pages = getPages(searchForm, reports);
		model.addAttribute("reports", pages.getContent());
		model.addAttribute("pages", pages);
		model.addAttribute("performanceMessage", getStatus(reports));
		return "reports/performanceList";
	}

	
	@Transient
	private String getStatus(List<AssignedReport> reports){
		List<AssignedReport> inTimeReports = new ArrayList<AssignedReport>();
		for (AssignedReport assignedReport : reports) {
			if(assignedReport.getEnd().equalsIgnoreCase("intime")){
				inTimeReports.add(assignedReport);
			}
		}
		
		if(reports.size() == 0){
			return "此次搜索共计"+reports.size() +" 条维修记录，  按时完成 "+ inTimeReports.size() +" 条记录， 按时完成率为   0%";
		}
		return "此次搜索共计"+reports.size() +" 条维修记录，  按时完成 "+ inTimeReports.size() +" 条记录， 按时完成率达 " + getPercent(inTimeReports.size(), reports.size()) + "%";
	}
	
	@Transient
	private String getPercent(int a, int b){
		float num= (float)a/b;  
		DecimalFormat df = new DecimalFormat("0.00");
		return df.format(num*100);
	}
	
	/**
	 * @param model
	 */
	private void initListPage(Model model) {
		model.addAttribute("customers", accountManager.getAllUser());
		model.addAttribute("users", accountManager.getAllUser());
	}

	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}

	@RequestMapping(value = "exportExcel")
	public String exportExcel(Model model, HttpServletRequest request ) throws JspTagException {
		String userName = getPrincipalProperty(SecurityUtils.getSubject().getPrincipal(), "name");
		@SuppressWarnings("unchecked")
		List<AssignedReport> reports = (List<AssignedReport>) request.getSession().getAttribute("performanceList");
		model.addAttribute("PerformanceReportView", reports);
		model.addAttribute("UserName", userName);
		return "performanceExcel";
	}
	

	@Transient
	 private String getPrincipalProperty(Object principal, String property) throws JspTagException {
	        String strValue = null;

	        try {
	            BeanInfo bi = Introspector.getBeanInfo(principal.getClass());

	            // Loop through the properties to get the string value of the specified property
	            boolean foundProperty = false;
	            for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
	                if (pd.getName().equals(property)) {
	                    Object value = pd.getReadMethod().invoke(principal, (Object[]) null);
	                    strValue = String.valueOf(value);
	                    foundProperty = true;
	                    break;
	                }
	            }

	            if (!foundProperty) {
	                final String message = "Property [" + property + "] not found in principal of type [" + principal.getClass().getName() + "]";
	                throw new JspTagException(message);
	            }

	        } catch (Exception e) {
	            final String message = "Error reading property [" + property + "] from principal of type [" + principal.getClass().getName() + "]";
	            throw new JspTagException(message, e);
	        }

	        return strValue;
	    }
	
}
